package com.flying.io;


import org.junit.Test;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/**
 * @author 刘鹏飞
 * @ClassName TestInputStreamReader
 * @Date 2025/2/17 21:21
 * @Created by 刘鹏飞
 * @Descriptio 转换流 --- 处理流
 */
public class TestInputStreamReader {


    public static void main(String[] args) {

        try (
                // 键盘输入相关流对象
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

                // 屏幕输入相关流
                BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))


        ) {

            // 读取键盘输入


            while (true) { // 输入 exit 退出

                bw.write("请输入: ");
                bw.newLine();
                bw.flush();


                //
                String s = br.readLine();

                // 程序退出
                if ("exit".equals(s) || "quit".equals(s)) {
                    bw.write("Bye Bye !!! ");
                    bw.flush();
                    break;
                }

                // 屏幕输出

                bw.write("输入的是:" + s);
                bw.newLine();
                bw.flush();


            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void test1() {

        // 读取字符的字符集于文件的编码集不一致

        try (FileReader fr = new FileReader("独白.txt")) {

            int str;
            while ((str = fr.read()) != -1) {
                // 乱码
                // utf8---> 读取 gbk
                System.out.print((char) str);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }


    }


    // 转换流
    // InputStreamReader/OutputStreamWriter用来实现将字节流转化成字符流。

    /**
     * InputStreamReader流对象的作用是:  提供字节流到字符流之间的转换
     * OutputStreamWriter流对象的作用是:  提供字符流到字节流之间的转换；
     */

    @Test
    public void test2() {

        // 读取字符的字符集于文件的编码集不一致

        try (FileInputStream fir = new FileInputStream("独白.txt");
             // 创建转换流(字节到字符的转换)流对象，并在该对象中指定编码
             InputStreamReader isr = new InputStreamReader(fir, "gbk");) {

            int str;
            while ((str = isr.read()) != -1) {
                // 乱码
                // utf8---> 读取 gbk
                System.out.print((char) str);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    /**
     * 通过字节流读取文本文件并添加行号
     */
    @Test
    public void test3() {


        try (
                //  1. 将字节流转换为字符流
                //  2. 缓冲字符流包裹字符流
                BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("独白.txt"), "gbk"));
                BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("独白1.txt"), StandardCharsets.UTF_8))

        ) {
            StringBuilder sb = new StringBuilder();
            String s = "";
            int i = 1;  // 行号自变量
            while ((s = br.readLine()) != null) {
                System.out.println(s);
                if (s.isEmpty()) {
                    bw.newLine();
                    continue;
                }
                bw.write(i + ". " + s);
                bw.newLine();
                i++;
            }

            bw.flush();


        } catch (IOException e) {
            //noinspection CallToPrintStackTrace
            e.printStackTrace();
        }


    }


    /**
     * 通过转换流实现键盘输入屏幕输出
     * public static final InputStream in =  null;    字节流
     * public static final PrintStream out = null;    打印流
     * public static final PrintStream err = null;
     * System.in: 节点流,控制台的输入
     * <p>
     * TODO:在Junit中无法获取键盘输入
     *     JUnit禁止直接键盘输入是出于自动化测试的可靠性考虑。应通过模拟输入、逻辑分离或Mock工具提供可控测试数据，从而确保测试快速、自动化运行。始终遵循以下原则：
     *     隔离性：测试不应依赖外部环境（如文件、网络、键盘）。
     *     确定性：给定相同输入，测试结果必须一致。
     */
    @Test
    public void test4() {

        try (
                // 键盘输入相关流对象
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

                // 屏幕输入相关流
                BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))


        ) {

            // 读取键盘输入


            while (true) { // 输入 exit 退出

                bw.write("请输入: ");
                bw.newLine();
                bw.flush();


                //
                String s = br.readLine();

                // 程序退出
                if ("exit".equals(s) || "quit".equals(s)) {
                    bw.write("Bye Bye !!! ");
                    bw.flush();
                    break;
                }

                // 屏幕输出

                bw.write("输入的是:" + s);
                bw.newLine();
                bw.flush();


            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void test5() {
        // 创建字符输入和输出流:使用转换流将字节流转换成字符流
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            bw = new BufferedWriter(new OutputStreamWriter(System.out));
            // 使用字符输入和输出流
            String str = br.readLine();
            // 一直读取，直到用户输入了exit为止
            while (!"exit".equals(str)) {
                // 写到控制台
                bw.write(str);
                bw.newLine();// 写一行后换行
                bw.flush();// 手动刷新
                // 再读一行
                str = br.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭字符输入和输出流
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }




}


